home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / telecomm / zmdm.zoo / common.c next >
Encoding:
C/C++ Source or Header  |  1991-04-27  |  36.2 KB  |  1,529 lines

  1. /*
  2.  *                ACKNOWLEDGEMENTS
  3.  *
  4.  *    ZMDM was derived from rz/sz for Unix  posted by 
  5.  *    Chuck Forsberg (...!tektronix!reed!omen!caf ). We
  6.  *    thank him for his excellent code, and for giving
  7.  *    us permission to use and distribute his code and
  8.  *    documentation.
  9.  *
  10.  *    Atari St version by:
  11.  *    Jwahar Bammi
  12.  *     bang:   {any internet host}!dsrgsun.ces.CWRU.edu!bammi
  13.  *     domain: bammi@dsrgsun.ces.CWRU.edu
  14.  *    GEnie:    J.Bammi
  15.  */
  16.  
  17. #include "config.h"
  18.  
  19. #define IN_COMMON
  20.  
  21. /*
  22.  * -rev 08-17-86
  23.  * mode function and most of the rest of the system dependent
  24.  * stuff for rb.c and sb.c   This file is #included so the includer
  25.  * can set parameters such as HOWMANY.  See the main file (rz.c/sz.c)
  26.  * for compile instructions.
  27.  */
  28.  
  29. #ifdef DLIBS
  30. #include <string.h>
  31. #endif
  32.  
  33. #include "zmdm.h"
  34. #include "zmodem.h"
  35.  
  36. #ifndef Supexec
  37.         /* Some versions of osbind don't define Supexec */
  38. #define Supexec(X) xbios(38,X)
  39. #endif
  40.  
  41. #define CRCTABLE
  42.  
  43.         /* GLOBALS */
  44. int Zmodem;        /* ZMODEM protocol requested */
  45. int Nozmodem;    /* If invoked as "rb" */
  46. int Batch;
  47. int Verbose;
  48. int Quiet;        /* overrides logic that would otherwise set verbose */
  49. int Lleft;        /* number of characters in linbuf */
  50. int Readnum;    /* Number of bytes to ask for in read() from modem */
  51. int Crcflg, Nflag;
  52. int ForceBinary;        /* local binary force override for rz */
  53. int Wcsmask;
  54.  
  55. FILE *logf;
  56. FILE *STDERR;
  57. int vdebug;    /* set if RDEBUG or SDEBUG */
  58.  
  59. char secbuf[TXBSIZE];
  60. char linbuf[KSIZE];
  61. #if (MWC || MANX || __GNUC__)            /* File i/o buffer */
  62. unsigned char *bufr;    /* In MWC, MANX or GNU it is lmalloc()'ed in main.c */
  63. #else
  64. #ifndef DYNABUF
  65. unsigned char bufr[BBUFSIZ];
  66. #else
  67. unsigned char *bufr;
  68. #endif /* DYNABUF */
  69. #endif
  70. int fout;
  71. int Lastrx;
  72. int Firstsec;
  73. int Eofseen;        /* indicates cpm eof (^Z) has been received */
  74. int BEofseen;        /* EOF seen on input set by fooseek */
  75. int errors;
  76. long Bytesleft;        /* number of bytes of incoming file left */
  77. long Modtime;        /* Unix style mod time for incoming file */
  78. unsigned int Filemode;    /* Unix style mode for incoming file */
  79. char Pathname[PATHLEN];
  80. char *Progname;        /* the name by which we were called */
  81.  
  82. int Thisbinary;        /* current file is to be received in bin mode */
  83. int Blklen;        /* record length of received packets */
  84. char Lzmanag;        /* Local file management request */
  85. char zconv;        /* ZMODEM file conversion request */
  86. char zmanag;        /* ZMODEM file management request */
  87. char ztrans;        /* ZMODEM file transport request */
  88.  
  89. jmp_buf tohere;        /* For the interrupt on RX timeout */
  90. jmp_buf abrtjmp;    /* for force abort */
  91. jmp_buf busjmp;        /* for bus errors */
  92. jmp_buf addrjmp;    /* for address errors */
  93. unsigned long BusErr, AddrErr;    /* saved vector addresses */
  94. int Zctlesc;        /* Encode control characters */
  95. int SendType;        /* Which send line to use    */
  96. int Modem;        /* Send using Xmodem */
  97. int lsct;
  98. int tryzhdrtype;    /* Header type to send corresponding to Last rx close */
  99. int Txfcs32;        /* TRUE means send binary frames with 32 bit FCS */
  100. long Thisflen;
  101. int Crc32t;        /* Controls 32 bit CRC being sent */
  102.             /* 1 == CRC32,  2 == CRC32 + RLE */
  103. int Crc32r;        /* Indicates/controls 32 bit CRC being received */
  104.             /* 0 == CRC16,  1 == CRC32,  2 == CRC32 + RLE */
  105. int Usevhdrs;        /* Use variable length headers */
  106. int Rxhlen;        /* Length of header received */
  107.  
  108.     /* Globals used by ZMODEM functions */
  109. int Rxframeind;        /* ZBIN or ZHEX indicates type of frame received */
  110. int Rxtype;        /* Type of header received */
  111. int Rxcount;        /* Count of data bytes received */
  112. int Rxtimeout;        /* Tenths of seconds to wait for something */
  113. int Znulls;        /* Number of nulls to send at beginning of ZDATA hdr */
  114. char Rxhdr[ZMAXHLEN];    /* Received header */
  115. char Txhdr[ZMAXHLEN];    /* Transmitted header */
  116. long Rxpos;        /* Received file position */
  117. long Txpos;        /* Transmitted file position */
  118. char Attn[ZATTNLEN+1];    /* Attention string rx sends to tx on err */
  119. char *Altcan;        /* Alternate canit string */
  120. int Zrwindow;        /* RX window size (controls garbage count) */
  121.  
  122.         /* Globals used by Sz */
  123. unsigned Txwindow; /* Control the size of the transmitted window */
  124. unsigned Txwspac;    /* Spacing between zcrcq requests */
  125. unsigned Txwcnt;    /* Counter used to space ack requests */
  126. long Lrxpos;        /* Receiver's last reported offset */
  127. int Lskipnocor;
  128. int Rxclob;    /* Clobber existing file */
  129.  
  130. char Lzconv;    /* Local ZMODEM file conversion request */
  131. char Lztrans;
  132. char *Cmdstr;        /* Pointer to the command string */
  133. int Optiong;        /* Let it rip no wait for sector ACK's */
  134. int Totsecs;        /* total number of sectors this file */
  135. int Command;        /* Send a command, then exit. */
  136. int Cmdack1;        /* Rx ACKs command, then do it */
  137. int Exitcode;
  138. int Testattn;        /* Force receiver to send Attn, etc with qbf. */
  139. int Wantfcs32;        /* want to send 32 bit FCS */
  140. jmp_buf intrjmp;    /* For the interrupt on RX CAN */
  141.  
  142. char *qbf;
  143. unsigned int Rxbuflen;    /* Receiver's max buffer length */
  144. int Cmdtries;
  145. int Filcnt;        /* count of number of files opened */
  146. int Lfseen;
  147. int Tframlen;        /* Override for tx frame length */
  148. int blkopt;        /* Override value for zmodem blklen */
  149. int Rxflags;
  150. int Ascii;        /* Add CR's for brain damaged programs */
  151. int Fullname;        /* transmit full pathname */
  152. int Unlinkafter;    /* Unlink file after it is sent */
  153. int Dottoslash;        /* Change foo.bar.baz to foo/bar/baz */
  154. int errcnt;        /* number of files unreadable */
  155. int siggi;        /* line interrupt enable flag     */
  156.  
  157. /* crctab calculated by Mark G. Mendel, Network Systems Corporation */
  158. unsigned int crctab[256] = {
  159.     0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  160.     0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  161.     0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  162.     0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  163.     0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  164.     0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  165.     0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  166.     0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  167.     0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  168.     0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  169.     0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  170.     0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  171.     0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  172.     0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  173.     0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  174.     0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  175.     0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  176.     0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  177.     0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
  178.     0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
  179.     0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
  180.     0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
  181.     0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
  182.     0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
  183.     0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  184.     0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
  185.     0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  186.     0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  187.     0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  188.     0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  189.     0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  190.     0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  191. };
  192.  
  193. /*
  194.  * Copyright (C) 1986 Gary S. Brown.  You may use this program, or
  195.  * code or tables extracted from it, as desired without restriction.
  196.  *
  197.  *   Need an unsigned type capable of holding 32 bits;
  198.  */
  199. typedef unsigned long int UNS_32_BITS;
  200.  
  201. /* First, the polynomial itself and its table of feedback terms.  The  */
  202. /* polynomial is                                                       */
  203. /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
  204. /* Note that we take it "backwards" and put the highest-order term in  */
  205. /* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
  206. /* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
  207. /* the MSB being 1.                                                    */
  208.  
  209. /* Note that the usual hardware shift register implementation, which   */
  210. /* is what we're using (we're merely optimizing it by doing eight-bit  */
  211. /* chunks at a time) shifts bits into the lowest-order term.  In our   */
  212. /* implementation, that means shifting towards the right.  Why do we   */
  213. /* do it this way?  Because the calculated CRC must be transmitted in  */
  214. /* order from highest-order term to lowest-order term.  UARTs transmit */
  215. /* characters in order from LSB to MSB.  By storing the CRC this way,  */
  216. /* we hand it to the UART in the order low-byte to high-byte; the UART */
  217. /* sends each low-bit to hight-bit; and the result is transmission bit */
  218. /* by bit from highest- to lowest-order term without requiring any bit */
  219. /* shuffling on our part.  Reception works similarly.                  */
  220.  
  221. /* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
  222. /*                                                                     */
  223. /*     The table can be generated at runtime if desired; code to do so */
  224. /*     is shown later.  It might not be obvious, but the feedback      */
  225. /*     terms simply represent the results of eight shift/xor opera-    */
  226. /*     tions for all combinations of data and CRC register values.     */
  227. /*                                                                     */
  228. /*     The values must be right-shifted by eight bits by the "updcrc"  */
  229. /*     logic; the shift must be unsigned (bring in zeroes).  On some   */
  230. /*     hardware you could probably optimize the shift in assembler by  */
  231. /*     using byte-swap instructions.                                   */
  232.  
  233. unsigned long int crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
  234.     0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
  235.     0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 
  236.     0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
  237.     0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 
  238.     0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  239.     0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 
  240.     0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
  241.     0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 
  242.     0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
  243.     0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 
  244.     0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
  245.     0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 
  246.     0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
  247.     0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 
  248.     0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  249.     0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 
  250.     0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
  251.     0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 
  252.     0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
  253.     0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 
  254.     0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
  255.     0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 
  256.     0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
  257.     0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 
  258.     0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  259.     0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 
  260.     0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
  261.     0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 
  262.     0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
  263.     0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 
  264.     0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
  265.     0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 
  266.     0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
  267.     0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 
  268.     0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  269.     0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 
  270.     0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
  271.     0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 
  272.     0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
  273.     0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 
  274.     0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
  275.     0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 
  276.     0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
  277.     0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 
  278.     0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  279.     0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 
  280.     0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
  281.     0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 
  282.     0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
  283.     0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 
  284.     0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
  285.     0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 
  286.     0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
  287.     0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 
  288.     0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  289.     0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 
  290.     0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
  291.     0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 
  292.     0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
  293.     0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 
  294.     0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 
  295.     0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 
  296.     0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 
  297.     0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL 
  298. }; 
  299.  
  300. #ifndef REMOTE
  301. int *aline_addr;        /* Base addr of aline variables */
  302. #endif
  303.  
  304. int hlines, ihlines;        /* # of lines on screen        */
  305. int rez;            /* current resolution        */
  306. int scolor = 0;            /* current fg/bg screen color toggle */
  307.  
  308. #ifndef REMOTE
  309. #ifndef OVERSCAN
  310. long *ms_ptr;            /* Pointer to my screen memory, aligned at
  311.                    a 256 bytes boundary */
  312. #else
  313. long *ms_ptr;            /* Pointer to my screen memory, aligned at */
  314. long *ms_log;            /* a 256 bytes boundary */
  315. #endif /* OVERSCAN */
  316.  
  317. #endif /* REMOTE */
  318.  
  319. #if (!(MWC || MANX || __GNUC__))
  320. #ifndef REMOTE
  321. long m_screen[8*1024+32];    /* My screen memory
  322.                    32K bytes + 256 Bytes guard for alignement
  323.                    In the worst case when we align we have to
  324.                    go 255 bytes from &m_screen[0], hence the
  325.                    256 Byte guard is required */
  326. #endif /* REMOTE */
  327.  
  328. #else /* MWC || MANX || __GNUC__ */
  329.  
  330. #ifdef RECURSE
  331. #ifdef BIGSTACK
  332. #if (MWC || __GNUC__)
  333. long _stksize = 128L * 1024L;
  334. #else
  335. long _STKSIZ = 128L * 1024L;
  336. #endif
  337. #else
  338. #if (MWC || __GNUC__)
  339. long _stksize = 16L * 1024L;
  340. #else
  341. long _STKSIZ = 16L * 1024L;
  342. #endif
  343. #endif /* BIGSTACK */
  344. #else
  345. #if (MWC || __GNUC__)
  346. long _stksize = 16384L;
  347. #else
  348. long _STKSIZ = 16384L;
  349. #endif
  350. #endif /* RECURSE */
  351.  
  352. #ifndef REMOTE
  353. long *m_screen;            /* Presently Mark Willams will not allow
  354.                    > 32K static structures */
  355. #endif /* REMOTE */
  356.  
  357. #endif /* MWC */
  358.  
  359. #ifdef DLIBS
  360. #ifdef RECURSE
  361. #ifdef BIGSTACK
  362. long _STKSIZE = 128L * 1024L;
  363. #else
  364. long _STKSIZE = 16L * 1024L;
  365. #endif /* BIGSTACK */
  366. #else
  367. long _STKSIZE = 16384L;
  368. #endif /* RECURSE */
  369. #endif /* DLIBS */
  370.  
  371. struct stat statbuf;          /* Disk Transfer address for Find first etc */
  372. int Baudrate;              /* Current baud rate                  */
  373. long drv_map;              /* bit vector of valid drives */
  374.  
  375. #ifndef    HIBAUD
  376. BAUDS vbauds[] = {
  377.     { "19200", 0, 19200 },
  378.     { "9600" , 1,  9600 },
  379.     { "4800" , 2,  4800 },
  380.     { "4800" , 2,  4800 },
  381.     { "2400" , 4,  2400 },
  382.     { "2400" , 4,  2400 },
  383.     { "2400" , 4,  2400 },
  384.     { "1200" , 7,  1200 },
  385.     { "1200" , 7,  1200 },
  386.     { "300"  , 9,   300 },
  387. #if 0
  388.     { "38400", 4, 3840  },    /* (4,1,8, -1, -1, -1) */
  389.     { "57000", 3, 5700  },    /* (3,1,8, -1, -1, -1) */
  390. #endif
  391.     { (char *)NULL, -1, -1 }
  392. };
  393. #else
  394. BAUDS vbauds[] = {
  395.     { "38400", 0, 38400 },
  396.     { "19200", 1, 19200 },
  397.     { "9600" , 2,  9600 },
  398.     { "4800" , 3,  4800 },
  399.     { "2400" , 4,  2400 },
  400.     { "1200" , 5,  1200 },
  401.     { "600"  , 6,   600 },
  402.     { "300"  , 7,   300 },
  403.     { (char *)NULL, -1, -1 }
  404. };
  405.  
  406. CBAUD cbauds[] = {
  407.     { 3, 2 },    /* 38400 : div 16, 2x */
  408.     { 3, 4 },    /* 19200 */
  409.     { 3, 8 },    /* 9600    */
  410.     { 3, 16 },    /* 4800    */
  411.     { 3, 32 },    /* 2400    */
  412.     { 3, 64 },    /* 1200    */
  413.     { 5, 32 },    /* 600    */
  414.     { 5, 64 }    /* 300    */
  415. };
  416. #endif /* HIBAUD */
  417.  
  418. #ifdef    FLOW_CTRL
  419. FLOWS vflows[] = {
  420.     { "none",                0},
  421.     { "XON/XOFF",            1},
  422.     { "RTS/CTS",            2},
  423.     { "both XON/XOFF & RTS/CTS",    3}
  424. };
  425. #endif /* FLOW_CTRL */
  426.  
  427.  
  428.  
  429. IOREC save,    /* the original Iorec is saved here for the duration of this
  430.            process */
  431.       *savep;    /* ptr returned by Iorec() */
  432.  
  433. char iobuf[IBUFSIZ]; /* My large Rs232 receive buffer */
  434.  
  435. #ifdef DYNABUF
  436. long BBUFSIZ;
  437. #endif /* DYNABUF */
  438.  
  439. #ifdef __GNUC__
  440. extern volatile long pr_time;
  441. #else
  442. extern long pr_time;
  443. #endif
  444. extern void rd_time();
  445.  
  446.         /* statics */ 
  447. static char *tsr_ptr = (char *)0x00fffa2dL; /* See St internals */
  448. static long *hz_200 =  (long *)0x000004ba; /* Yes the Hitch Hikers */
  449.                        /* Guide is wrong!! */
  450.  
  451. static long 
  452.      alrm_time = 0L;      /* Time of next timeout (200 Hz) */ 
  453.  
  454. static char *special[] = { 
  455. ".PRG", ".TOS", ".TTP", ".ARC", ".ACC", ".IMG", ".RSC", ".O",
  456. ".OBJ", ".NEO", ".ZOO", ".CZ" , ".HZ" , ".GF" , ".PK" , ".LZH",
  457. ".PIC", ".PI1", ".PI2", ".PI3", ".PQ1", ".PQ2", ".PQ3", ".BRD",
  458. ".ANI", ".STW", ".OLB", ".LZS",
  459. ".FNT", ".PRT", ".SNG", ".NEC", ".CNF", ".Z"  , ".DFN", ".GEM",
  460. ".EZD", ".LNK", 
  461. ".SYM", ".DVI", ".PIX", ".X32", ".OUT", ".A",   ".CCC", ".CL",
  462. ".CMD", ".COM", 
  463. ".CRL", ".DAT", ".DIR", ".EXE", ".OVL", ".PAG", ".REL", ".SAV",
  464. ".SUB", ".SWP", 
  465. ".SYS", ".TAR", ".UTL", ".BIN", ".LBR", ".IM",  ".PAK",
  466. ".SBM", ".OBM", ".DIC", ".NDX", ".TFM", ".PBM", ".PBP", ".PCC",
  467. ".PXL", ".SYM", ".EL",  ".ELC",
  468. "" 
  469. }; 
  470. static char *in();
  471.  
  472. /* 
  473.  * mode(n) 
  474.  *  2: set a cbreak, XON/XOFF control mode if using Pro-YAM's -g
  475.  option 
  476.  *  1: save old tty stat, set raw mode  
  477.  *  0: restore original tty mode 
  478.  */
  479. mode(n)
  480. int n;
  481. {
  482.  
  483.     vfile("mode:%d", n);
  484.     switch(n) {
  485.  
  486.     case 2:    /* Cbreak mode used by sb when -g detected */
  487.         return OK;
  488.     case 1:
  489.         return OK;
  490.     case 0:
  491.         while(Bconstat(1)) Bconin(1);    /* flush input              */
  492.  
  493.         return OK;
  494.     default:
  495.         return ERROR;
  496.     }
  497. }
  498.  
  499. /*
  500.  * send a break
  501.  * Modifies Bit 3 in the TSR (reg 23) of the Mfp
  502.  */
  503.  
  504. sendbrk()
  505. {
  506.     register long save_ssp;
  507.     register long time;
  508.  
  509.     save_ssp = Super(0L);    /* Super Mode */
  510.  
  511.     /* set bit 3 of the TSR */
  512.     *tsr_ptr |= (char)8;
  513.  
  514.     
  515.     /* wait for 250 ms */
  516.     time = *hz_200 + 50;
  517.     while(*hz_200 < time)
  518.         /* wait */ ;
  519.  
  520.     /* reset bit 3 of the tsr */
  521.     *tsr_ptr &= (char)~8;
  522.  
  523.     Super(save_ssp);    /* Back to user Mode */
  524. }
  525.  
  526. #ifdef TX
  527. /*
  528.  * Put transmit section of the MFP uart off
  529.  *
  530.  */
  531. Txoff()
  532. {
  533.     register long save_ssp;
  534.  
  535.     save_ssp = Super(0L);    /* Super Mode */
  536.     
  537.     /* clear bit 0 of the tsr */
  538.     *tsr_ptr &= (char)~1;
  539.  
  540.     Super(save_ssp);    /* Back to user Mode */
  541. }
  542.  
  543. /*
  544.  * Put transmit section of the MFP uart on
  545.  *
  546.  */
  547. Txon()
  548. {
  549.     register long save_ssp;
  550.  
  551.     save_ssp = Super(0L);    /* Super Mode */
  552.     
  553.     /* set bit 0 of the tsr */
  554.     *tsr_ptr |= (char)1;
  555.  
  556.     Super(save_ssp);    /* Back to user Mode */
  557. }
  558. #endif /* TX */
  559.  
  560.  
  561. /*
  562.  * read_modem() - read upto count characters from the modem port
  563.  * Check for user abort (^C) and timeout at the same time
  564.  */
  565. int read_modem(buf, count)
  566. register char *buf;
  567. register int count;
  568. {
  569.     register int n;
  570.     extern void rd_time();
  571.  
  572.     n = 0;
  573.  
  574.     while(1)
  575.     {
  576. #ifndef REMOTE
  577.         if(Bconstat(2))
  578.         {
  579.             /* Character Hit at the Keyboard - is it ^C */
  580.             if((Bconin(2) & 0x7f) == CTRL('C'))
  581.             {
  582.                 /* It is a Control-C */
  583.                 if(SendType)
  584.                     bibis(3);
  585.                 else
  586.                     bibi(3);
  587.             }
  588.             
  589.         }
  590. #endif
  591.         if(Bconstat(1))
  592.         {
  593.             /* Character available at Modem Port */
  594.             n++;
  595.             *buf++ = Bconin(1);
  596.  
  597.             while((n < count)  && Bconstat(1))
  598.             {
  599.                 *buf++ = Bconin(1);
  600.                 n++;
  601.  
  602.             }
  603.             return n;
  604.         }
  605.         
  606.         /* Check for time out if required */
  607.         if(alrm_time != 0)
  608.         {
  609.             /* Alarm Set */
  610.             Supexec(rd_time);
  611.             if(pr_time >= alrm_time)
  612.                 /* timeout */
  613.                 longjmp(tohere, -1);
  614.         }
  615.     }
  616. }
  617.  
  618.  
  619. /*
  620.  * alarm() - set the alarm time
  621.  */
  622. void stalarm(n)
  623. unsigned int n;
  624. {
  625.     extern void rd_time();
  626.  
  627.     if(n > 0)
  628.     {
  629.         Supexec(rd_time);
  630.         /* We really need n * 200 but n * 256 is close enough */
  631.         alrm_time = pr_time + ( n << 8 );
  632.     }
  633.     else
  634.         alrm_time = 0L;
  635. }
  636.  
  637. /*
  638.  * write_modem() - send buffer to the modem port
  639.  *
  640. */
  641. void write_modem(buf,len)
  642. register char *buf;
  643. register int len;
  644. {
  645.     while(len-- > 0)
  646.            Bconout(1, *buf++);
  647. }
  648.  
  649.  
  650. /*
  651.  * flushinput() - flush any characters in the modem port
  652.  * a future enhancement may be flush any characters that are in there
  653.  * and any that come in over the next 1 second -- Ymodem does that
  654.  *
  655.  */
  656. void flushinput()
  657. {
  658.     while(Bconstat(1))
  659.         Bconin(1);
  660. }
  661.  
  662.  
  663.  
  664. int isbinary(name)
  665. register char *name;
  666. {
  667.     register char **p;
  668.     register char *ext;
  669.     extern char *rindex();
  670.     extern int ustrcmp();
  671.     
  672.     if((ext = rindex(name,'.')) == (char *)NULL)
  673.     {
  674.         return 0;
  675.     }
  676.     
  677.     for(p = special; **p != '\0'; p++)
  678.         if(ustrcmp(ext,*p) == 0)
  679.         return 1;
  680.     return 0;
  681. }
  682.  
  683. #define upper(X) (islower(X)?toupper(X):X)
  684.  
  685. /* Strcmp - case insensative */
  686. int ustrcmp(s1,s2)
  687. register char *s1, *s2;
  688. {
  689.     while(*s1 != '\0')
  690.     {
  691.         if(*s2 == '\0')
  692.             return 1;
  693.         if(upper(*s1) != *s2)
  694.             return 1;
  695.         s1++;
  696.         s2++;
  697.     }
  698.     if(*s2 != '\0')
  699.         return 1;
  700.     else
  701.         return 0;
  702. }
  703.  
  704.  
  705. /*
  706.  * Ensure that each subdirectory in the pathname exists.
  707.  * If one doesn'nt, make the rest of the directory
  708.  * Returns ERROR if it has trouble creating a path
  709.  *
  710.  */
  711. int pathensure(name)
  712. char *name;
  713. {
  714.     extern char *index();
  715.  
  716.     if(index(name, '\\') == (char *)NULL)
  717.         /* nothing to check */
  718.         return OK;
  719.  
  720.     return pathrest(name, (char *)NULL);
  721. }
  722.  
  723. /*
  724.  * check rest of the path recursively
  725.  *    If any component of the path name is longer than 8/12 characters then
  726.  *    warn.
  727.  *
  728.  */
  729. int pathrest(name, prev)
  730. char *name, *prev;
  731. {
  732.     char previous[128];
  733.     char component[13];
  734.     register char *p, *q, *r, *s;
  735.     register int warn;
  736.     extern char *index();
  737.     extern char *in();
  738.  
  739.     if((r = index(name, '\\')) == (char *)NULL)
  740.         /* nothing more to check */
  741.         return OK;
  742.  
  743.     /* pick up the next component of the path name, 8/12 chars max for ST */
  744.     warn = 0;
  745.     if((s = in(name, r, '.')) == (char *)NULL)
  746.     {
  747.         /* component does'nt contain a dot */
  748.         if( ((long)r - (long)name) > 8)
  749.         {
  750.             warn++;
  751.             strncpy(component, name, 8);
  752.             q = &component[8];
  753.         }
  754.         else
  755.         {
  756.             register int n;
  757.  
  758.             n = (int)((long)r - (long)name);
  759.             strncpy(component, name, n);
  760.             component[n] = '\0';
  761.             q = &component[((int)strlen(component))];
  762.         }
  763.     }
  764.     else
  765.     {
  766.         /* component contains a dot */
  767.         if(((long)s - (long)name) > 8)
  768.         {
  769.             warn++;
  770.             strncpy(component, name, 8);
  771.             q = &component[8];
  772.         }
  773.         else
  774.         {
  775.             for(p = name, q = component; p != s; )
  776.                 *q++ = *p++;
  777.         }
  778.         *q++ = '.';
  779.         s++;
  780.         if(s != r)
  781.         {
  782.             if(((long)r - (long)s) > 3)
  783.             {
  784.                 warn++;
  785.                 strncpy(q, s, 3);
  786.                 q = &q[3];
  787.             }
  788.             else
  789.             {
  790.                 for(p = s; p != r; )
  791.                     *q++ = *p++;
  792.             }
  793.         }
  794.     }
  795.     *q = '\0';
  796.  
  797. #ifndef REMOTE
  798.     if(warn)
  799.     {
  800.         fprintf(stderr,
  801.         "?WARNING - A component of the path is longer than 8/12 chars\n");
  802.         fprintf(stderr,"%s --> %s\n", name, component);
  803.     }
  804. #endif
  805.     if(prev == (char *)NULL)
  806.         strcpy(previous, component);
  807.     else
  808.     {
  809.         strcpy(previous, prev);
  810.         strcat(previous, "\\");
  811.         strcat(previous, component);        
  812.     }
  813.  
  814.     if(existd(previous))
  815.         /* it exists - go do rest */
  816.         return pathrest(++r, previous);
  817.  
  818.     /* does not exist,                 */
  819.     /* make this component and all its children */
  820.     return makesubtree(++r, previous);
  821. }
  822.  
  823. /*
  824.  * make a subtree
  825.  */
  826. int makesubtree(name, prev)
  827. char *name, *prev;
  828. {
  829.     char previous[128];
  830.     char component[13];
  831.     register char *p, *q, *r, *s;
  832.     register int warn;
  833.     extern char *index();
  834.     extern char *in();
  835.  
  836.     if(Dcreate(prev) != 0)
  837.     {
  838.         log2("Trouble trying to create subtree\n");
  839.         fprintf(STDERR,"%s\n", prev);
  840.         return ERROR;
  841.     }
  842. #ifndef REMOTE
  843.     fprintf(stderr,"Created Directory %s\n", prev);
  844. #endif
  845.     if((r = index(name, '\\')) == (char *)NULL)
  846.         /* nothing more to do */
  847.         return OK;
  848.  
  849.     /* pick up the next component of the path name, 8/12 chars max for ST */
  850.     warn = 0;
  851.     if((s = in(name, r, '.')) == (char *)NULL)
  852.     {
  853.         /* component does'nt contain a dot */
  854.         if( ((long)r - (long)name) > 8)
  855.         {
  856.             warn++;
  857.             strncpy(component, name, 8);
  858.             q = &component[8];
  859.         }
  860.         else
  861.         {
  862.             register int n;
  863.  
  864.             n = (int)((long)r - (long)name);
  865.             strncpy(component, name, n);
  866.             component[n] = '\0';
  867.             q = &component[((int)strlen(component))];
  868.         }
  869.     }
  870.     else
  871.     {
  872.         /* component contains a dot */
  873.         if(((long)s - (long)name) > 8)
  874.         {
  875.             warn++;
  876.             strncpy(component, name, 8);
  877.             q = &component[8];
  878.         }
  879.         else
  880.         {
  881.             for(p = name, q = component; p != s; )
  882.                 *q++ = *p++;
  883.         }
  884.         *q++ = '.';
  885.         s++;
  886.         if(s != r)
  887.         {
  888.             if(((long)r - (long)s) > 3)
  889.             {
  890.                 warn++;
  891.                 strncpy(q, s, 3);
  892.                 q = &q[3];
  893.             }
  894.             else
  895.             {
  896.                 for(p = s; p != r; )
  897.                     *q++ = *p++;
  898.             }
  899.         }
  900.     }
  901.     *q = '\0';
  902.  
  903. #ifndef REMOTE
  904.     if(warn)
  905.     {
  906.         fprintf(stderr,
  907.         "?WARNING - A component of the path is longer than 8/12 chars\n");
  908.         fprintf(stderr,"%s --> %s\n", name, component);
  909.     }
  910. #endif
  911.     strcpy(previous, prev);
  912.     strcat(previous, "\\");
  913.     strcat(previous, component);        
  914.  
  915.  
  916.  
  917.     /* go do the rest of them */
  918.     return makesubtree(++r, previous);
  919. }
  920.  
  921.  
  922. /*
  923.  * test if a subdirectory exists
  924.  * include special case of 'D:\' that Fsfirst does'nt handle correctly
  925.  */
  926. int existd(name)
  927. register char *name;
  928. {
  929.     /* assuming the DTA buffer is already set up */
  930.     extern long drv_map;
  931.     extern struct stat statbuf;
  932.     register int drive;
  933.     
  934.     if (Fsfirst(name , 0x0021|0x0010) == 0)
  935.     {
  936.         if((statbuf.st_mode & 0x0010) == 0x0010)
  937.             return TRUE;
  938.     }
  939.  
  940.     /* Gemdos doesn't like d:\ style dirs */
  941.     if((name[3] == '\0') && (name[2] == '\\') && (name[1] == ':'))
  942.     {
  943.         drive = name[0];
  944.         if(isupper(drive))
  945.             drive = tolower(drive);
  946.  
  947.         drive = drive - 'a';
  948.         if((drv_map & (1L << drive)) == 0)
  949.             return FALSE;
  950.         else
  951.             return TRUE;
  952.     }
  953.     /* Nor does Gemdos understand '.' or '..' */
  954.     /* Hey Atari, don't you guys ever test anything */
  955.     if((strcmp(name,".") == 0) || (strcmp(name,"..") == 0) ||
  956.        (strcmp(name,".\\") == 0) || (strcmp(name,"..\\") == 0))
  957.         return TRUE;
  958.  
  959.     return FALSE;
  960. }
  961.  
  962. /*
  963.  * Does a file exist
  964.  */
  965. int existf(name)
  966. register char *name;
  967. {
  968.     /* assuming the DTA buffer is already set up */
  969.     
  970.     return (Fsfirst(name , 0x0001) == 0);
  971.  
  972. }
  973.  
  974. /*
  975.  * stsystem(cmd) - execute a process
  976.  * char *cmd;   command to execute (including redirections etc)
  977.  */
  978. int stsystem(cmd)
  979. char *cmd;
  980. {
  981.         register char *ptr1;             /* general pointers */
  982.         register char save;              /* */
  983.         register int status;            /* return status       */
  984.         register char *args;            /* arguments            */
  985.         register int len;               /* length of args - 2   */
  986.         char nils[2];
  987. #ifdef __GNUC__
  988.         extern void *malloc(size_t);
  989. #else
  990.         extern char *malloc();
  991. #endif
  992.  
  993.  
  994.         nils[0] = nils[1] = '\0';
  995.         for(ptr1 = cmd; (!isspace(*ptr1)) && (*ptr1 != '\0'); ptr1++)
  996.                 /* skip till end of path name */;
  997.         if(*ptr1 != '\0')
  998.         {
  999.                 /* cmd does have a command tail */
  1000.                 /* save the char at the position and terminate the path */
  1001.                 save = *ptr1;
  1002.                 *ptr1++ = '\0'; /* command tail is the rest of it */
  1003.  
  1004. #ifdef __GNUC__
  1005.                 if((args = (char *) malloc((size_t)((len = strlen(ptr1)) + 2)))
  1006. #else
  1007.                 if((args = (char *) malloc((len = strlen(ptr1)) + 2))
  1008. #endif
  1009.                     == (char *)NULL)
  1010.                 {
  1011.                         /* could not allocate memory */
  1012.                         return(-1);
  1013.                 }
  1014.                 *args++ = len;
  1015.                 strcpy(args,ptr1);
  1016.                 args--;
  1017.                 /* now do the load and go */
  1018.                 status = Pexec(0,cmd,args,(char *)NULL);
  1019.                 /* restore cmd to original state */
  1020.                 *--ptr1 = save;
  1021.                 free(args);
  1022.         }
  1023.         else
  1024.         {
  1025.                 /* command does not have a tail */
  1026.  
  1027.                 /* now do the load and go */
  1028.                 status = Pexec(0,cmd,nils,(char *)NULL);
  1029.         }
  1030.  
  1031.         return(status);
  1032. }
  1033.  
  1034. stsleep(n)
  1035. int n;
  1036. {
  1037.     extern void rd_time();
  1038.  
  1039.     if(n != 0)
  1040.     {
  1041.         Supexec(rd_time);
  1042.         /* We really need n * 200 but n * 256 if close enough */
  1043.         alrm_time = pr_time + ( n << 8 );
  1044.  
  1045.         while(alrm_time > pr_time)
  1046.         {
  1047.             Supexec(rd_time);
  1048.         }
  1049.         alrm_time = 0L;
  1050.     }
  1051. }
  1052.  
  1053.  
  1054. initz()
  1055. {
  1056.      Zmodem=0;        /* ZMODEM protocol requested */
  1057.      Nozmodem = 0;        /* If invoked as "rb" */
  1058.      Batch=0;
  1059.      Verbose=0;
  1060.      lsct = 1;
  1061.      Quiet=0;        /* overrides logic that would otherwise set verbose */
  1062.      Lleft=0;        /* number of characters in linbuf */
  1063.  
  1064.      logf = (FILE *)NULL;
  1065.      vdebug = 0;
  1066.  
  1067.      Readnum = KSIZE;    /* Number of bytes to ask for in read() from modem */
  1068.      Crcflg = FALSE;
  1069.      Wcsmask = 0377;
  1070.      Modtime = 0;
  1071.      Nflag = FALSE;
  1072.      fout = (-1);
  1073.      errors = 0;
  1074.      Rxtimeout = 100;    /* Tenths of seconds to wait for something */
  1075.      Modem = 0;
  1076.      Blklen = SECSIZ;    /* record length of received packets */
  1077.  
  1078.     qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n";
  1079.     Cmdtries = 11;
  1080.     Filcnt=0;        /* count of number of files opened */
  1081.     Lfseen=0;
  1082.     Rxbuflen = (unsigned)16384;    /* Receiver's max buffer length */
  1083.     Tframlen = 0;        /* Override for tx frame length */
  1084.     blkopt=0;        /* Override value for zmodem blklen */
  1085.     Rxflags = 0;
  1086.     Ascii=0;        /* Add CR's for brain damaged programs */
  1087.     Fullname=0;        /* transmit full pathname */
  1088.     Unlinkafter=0;        /* Unlink file after it is sent */
  1089.     Dottoslash=0;        /* Change foo.bar.baz to foo/bar/baz */
  1090.     errcnt=0;        /* number of files unreadable */
  1091.     Testattn = FALSE;
  1092.     siggi = 0;
  1093.     Command = FALSE;
  1094.     Wantfcs32 = TRUE;    /* want to send 32 bit FCS */
  1095.     Znulls = 0;
  1096.     tryzhdrtype=ZRINIT;    /* Header type to send corresponding to Last rx close */
  1097.     Txfcs32 = FALSE;    /* TRUE means send binary frames with 32 bit FCS */
  1098.     ForceBinary = FALSE;    /* Local force binary override for rz */
  1099.      
  1100.      Txwindow = 0; /* Control the size of the transmitted window */
  1101.      Txwspac= 0;    /* Spacing between zcrcq requests */
  1102.      Txwcnt = 0;    /* Counter used to space ack requests */
  1103.      Lrxpos = 0;        /* Receiver's last reported offset */
  1104.      Lskipnocor = 0;
  1105.      Zrwindow = 1400;    /* RX window size (controls garbage count) */
  1106.      Rxclob=TRUE;    /* Clobber existing file */
  1107.     Crc32r = 0;
  1108.     Crc32t = 0;
  1109.     Zctlesc = 0;
  1110.     Optiong = FALSE;
  1111.     Usevhdrs = 0;        /* Use variable length headers */
  1112.      Rxhlen = 0;
  1113.      Thisflen = 0L;
  1114.      Lztrans = 0;
  1115.      Lzmanag = 0;
  1116.      Lzconv = 0;
  1117.      Cmdack1 = 0;
  1118.      Eofseen = 0;        /* EOF seen on input set by zfilbuf */
  1119.      BEofseen = 0;        /* EOF seen on input set by fooseek */
  1120.  
  1121. }
  1122.  
  1123. /* abort current session - due to async fault */
  1124. aexit(n)
  1125. int n;
  1126. {
  1127.     longjmp(abrtjmp, n);
  1128. }
  1129.  
  1130. buserr()
  1131. {
  1132.     longjmp(busjmp, -1);
  1133. }
  1134.  
  1135. addrerr()
  1136. {
  1137.     longjmp(addrjmp, -1);
  1138. }
  1139.  
  1140. /*
  1141.  * Local console output simulation
  1142.  */
  1143. bttyout(c)
  1144. int c;
  1145. {
  1146.     if (Verbose)
  1147. #ifdef REMOTE
  1148.         Bconout(1, c);
  1149. #else
  1150.         putc(c, stderr);
  1151. #endif
  1152. }
  1153.  
  1154. /*
  1155.  *  Send a character to modem.  Small is beautiful.
  1156.  */
  1157. #ifndef __GNUC__
  1158. void sendline(c)
  1159. int c;
  1160. {
  1161. #ifndef REMOTE
  1162.     if (Verbose>4)
  1163.     {
  1164.         fprintf(stderr, "Sendline: %x\n", c);
  1165.  
  1166.     }
  1167. #endif
  1168.     if (SendType)
  1169.         Bconout(1, c & 0377);
  1170.     else
  1171.         Bconout(1, c);
  1172.  
  1173. }
  1174.  
  1175. void flush_modem()
  1176. {
  1177.     while(Bcostat(1) == 0);
  1178. }
  1179. #endif /* __GNUC__ */
  1180.  
  1181.  
  1182. /*
  1183.  * substr(string, token) searches for token in string s
  1184.  * returns pointer to token within string if found, NULL otherwise
  1185.  */
  1186. char *
  1187. substr(s, t)
  1188. register char *s;
  1189. char *t;
  1190. {
  1191.     register char *ss,*tt;
  1192.     /* search for first char of token */
  1193.     for (ss=s; *s; s++)
  1194.         if (*s == *t)
  1195.             /* compare token with substring */
  1196.             for (ss=s,tt=t; ;)
  1197.             {
  1198.                 if (*tt == '\0')
  1199.                     return s;
  1200.                 if (*ss++ != *tt++)
  1201.                     break;
  1202.             }
  1203.  
  1204.     return ((char *)NULL);
  1205. }
  1206.  
  1207.  
  1208. /* send cancel string to get the other end to shut up */
  1209. canit()
  1210. {
  1211.     static char canistr[] = {
  1212.      ZPAD,ZPAD,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  1213.     };
  1214.  
  1215.     write_modem(canistr, (int)strlen(canistr));
  1216.     if(!SendType)
  1217.         Lleft=0;    /* Do read next time ... */
  1218.  
  1219. }
  1220.  
  1221.  
  1222. /*
  1223.  *  Debugging information output interface routine
  1224.  */
  1225. /* VARARGS1 */
  1226. vfile(f, a, b, c)
  1227. register char *f;
  1228. int a, b, c;
  1229. {
  1230.     if (Verbose > 3)
  1231.     {    /* verbose 2 is normal for us */
  1232.         fprintf(STDERR, f, a, b, c);
  1233.         fprintf(STDERR, "\n");
  1234.  
  1235.         if(vdebug && (logf != (FILE *)NULL))
  1236.         {
  1237.             fprintf(logf, f, a, b, c);
  1238.             fprintf(logf, "\n");
  1239.             fflush(logf);
  1240.         }
  1241.  
  1242.     }
  1243. }
  1244.  
  1245. /* longs and pointers are not integers */
  1246. /* VARARGS1 */
  1247. vfile2(f, a, b, c)
  1248. long a, b, c;
  1249. register char *f;
  1250. {
  1251.     if (Verbose > 3)
  1252.     {
  1253.         fprintf(STDERR, f, a, b, c);
  1254.         fprintf(STDERR, "\n");
  1255.  
  1256.         if(vdebug && (logf != (FILE *)NULL))
  1257.         {
  1258.             fprintf(logf, f, a, b, c);
  1259.             fprintf(logf, "\n");
  1260.             fflush(logf);
  1261.         }
  1262.  
  1263.     }
  1264. }
  1265.  
  1266. static char *in(from, to, c)
  1267. register char *from, *to;
  1268. register int c;
  1269. {
  1270.     for(; from < to; from++)
  1271.     {
  1272.         if(*from == c)
  1273.             return from;
  1274.     }
  1275.     return (char *)NULL;
  1276. }
  1277.  
  1278. /*
  1279.  * SetIoBuf() - Save the systems Rs232 buffer and install my large
  1280.  * Rs232 buffer.
  1281.  *
  1282.  */
  1283. void SetIoBuf()
  1284. {
  1285.     /* Get pointer to Rs232 input record */
  1286.     savep = (IOREC *)Iorec(0);
  1287.     
  1288.     /* Save the info */
  1289.     save.ibuf    = savep->ibuf;
  1290.     save.ibufsiz    = savep->ibufsiz;
  1291.     save.ibufhd    = savep->ibufhd;
  1292.     save.ibuftl    = savep->ibuftl;
  1293.     save.ibuflow    = savep->ibuflow;
  1294.     save.ibufhi    = savep->ibufhi;
  1295.  
  1296.     
  1297.     /* Install my buffer in its place */
  1298.     savep->ibuf        = &iobuf[0];
  1299.     savep->ibufsiz    = IBUFSIZ;
  1300.     savep->ibuflow    = IBUFSIZ/8;
  1301.     savep->ibufhi    = (IBUFSIZ / 4) * 3;
  1302.     savep->ibufhd = savep->ibuftl = 0;
  1303.  
  1304.     
  1305. }
  1306.  
  1307. /*
  1308.  * ResetIoBuf() - Reset the Rs232 buffer to the saved (system's) buffer
  1309.  *
  1310.  */
  1311. void ResetIoBuf()
  1312. {
  1313.     savep->ibuf    = save.ibuf;
  1314.     savep->ibufsiz    = save.ibufsiz;
  1315.     savep->ibuflow    = save.ibuflow;
  1316.     savep->ibufhi    = save.ibufhi;
  1317.     savep->ibufhd    = save.ibufhd;
  1318.     savep->ibuftl    = save.ibuftl;
  1319.  
  1320. }
  1321.  
  1322.  
  1323. /*
  1324.  * Log an error if verbose
  1325.  */
  1326.  
  1327. /*VARARGS1*/
  1328. log2(s,p,u)
  1329. char *s;
  1330. int p, u;
  1331. {
  1332.     if (!Verbose)
  1333.         return;
  1334.     fprintf(STDERR, "\nerror %d: ", errors);
  1335.     fprintf(STDERR, s, p, u);
  1336.  
  1337. #ifdef RDEBUG
  1338.     if(Verbose > 3)
  1339.     {
  1340.         fprintf(logf, "error %d: ", errors);
  1341.         fprintf(logf, s, p, u);
  1342.     }
  1343. #endif
  1344.  
  1345. }
  1346. /*
  1347.  * This version of readline is reasonably well suited for
  1348.  * reading many characters.
  1349.  * timeout is in tenths of seconds
  1350.  */
  1351. int readline(timeout)
  1352. int timeout;
  1353. {
  1354. #ifdef __GNUC__
  1355.     volatile int n;
  1356. #else
  1357.     register int n;
  1358. #endif
  1359.     static char *cdq;    /* pointer for removing chars from linbuf */
  1360.  
  1361.     if (--Lleft >= 0)
  1362.     {
  1363. #ifdef RDEBUG
  1364.         if (Verbose > 8)
  1365.         {
  1366.             fprintf(logf, "%02x ", *cdq&0377);
  1367.         }
  1368. #endif
  1369.  
  1370.         return (*cdq++ & 0377);
  1371.     }
  1372. /*    n = timeout/10; */
  1373.     n = timeout >> 3;  /* close enough for rock and roll - see alarm() */
  1374.     if (n < 2)
  1375.         n = 3;
  1376. #ifdef RDEBUG
  1377.     if (Verbose > 3)
  1378.         fprintf(logf, "Calling read: n=%d ", n);
  1379. #endif
  1380.  
  1381.     if (setjmp(tohere))
  1382.     {
  1383.         Lleft = 0;
  1384. #ifdef RDEBUG
  1385.         if (Verbose>3)
  1386.         {
  1387.             fprintf(STDERR, "Readline:TIMEOUT\n");
  1388.             fprintf(logf, "Readline:TIMEOUT\n");
  1389.  
  1390.         }
  1391. #endif
  1392.         return TIMEOUT;
  1393.     }
  1394.     stalarm(n);
  1395.     Lleft=read_modem(cdq=linbuf, Readnum);
  1396.     stalarm(0);
  1397.  
  1398. #ifdef RDEBUG
  1399.     if (Verbose > 3)
  1400.     {
  1401.         fprintf(logf, "Read returned %d bytes\n", Lleft);
  1402.     }
  1403. #endif
  1404.  
  1405.     if (Lleft < 1)
  1406.         return TIMEOUT;
  1407.     --Lleft;
  1408.  
  1409. #ifdef RDEBUG
  1410.     if (Verbose > 8)
  1411.     {
  1412.         fprintf(logf, "%02x ", *cdq&0377);
  1413.     }
  1414. #endif
  1415.  
  1416.     return (*cdq++ & 0377);
  1417. }
  1418.  
  1419. report(sct)
  1420. int sct;
  1421. {
  1422. #ifndef REMOTE
  1423.     if (Verbose>1)
  1424.         fprintf(STDERR,"%03d%c",sct,sct%10? ' ' : '\r');
  1425. #endif
  1426. }
  1427.  
  1428. lreport(sct)
  1429. long sct;
  1430. {
  1431. #ifndef REMOTE
  1432.     if (Verbose>1)
  1433.         fprintf(STDERR,"%06ld%c",sct,lsct%10? ' ' : '\r');
  1434.     lsct++;
  1435. #endif
  1436. }
  1437.  
  1438.  
  1439. #ifdef DLIBS
  1440. _initargs()
  1441. {
  1442. }
  1443. #endif
  1444.  
  1445. wr_modem(s)
  1446. register char *s;
  1447. {
  1448.     while(*s != '\0')
  1449.         Bconout(1, *s++);
  1450. }
  1451.  
  1452. #ifdef DYNABUF
  1453. unsigned char *dalloc()
  1454. {
  1455.     register long avail;
  1456.  
  1457.     if((avail = (long)Malloc(-1L) - LEAVEALONE) < MINACC)
  1458.         return (unsigned char *)NULL;
  1459.  
  1460.     BBUFSIZ = avail;
  1461.     return (unsigned char *)Malloc(BBUFSIZ);
  1462. }
  1463. #endif /* DYNABUF */
  1464.  
  1465. /* *******************************************************
  1466.     This code courtesy of katzung@laidbak.UUCP
  1467.      -- thank you very much 
  1468.    ******************************************************* */
  1469.  
  1470.  
  1471. /* From laidbak!katzung@Sun.COM Tue Apr 26 19:34:41 1988
  1472. Return-Path: <laidbak!katzung@Sun.COM>
  1473. From: Brian Katzung <laidbak!katzung@Sun.COM>
  1474. To: bammi@mandrill.CES.CWRU.Edu
  1475. Subject: Re:  UW
  1476. */
  1477.  
  1478. #define    MFP    0xFFFFFA01L
  1479. #define    TDDR    36
  1480. #define    hz_200    ((unsigned long *) 0x4BAL)
  1481.  
  1482. /* Baud rates 75 (120) and 50 (80) are not currently decoded. */
  1483. #ifndef    HIBAUD
  1484. static int    timevals[] = {
  1485.     1,    2,    4,    5,    8,    10,    11,
  1486.     16,    32,    64,    96,    128,    143,    175
  1487. };
  1488. #else
  1489. /* 300 & 600 overlap 1200 & 2400 */
  1490. static int    timevals[] = {
  1491.     2,    4,    8,    16,    32,    64
  1492. };
  1493. #endif /* HIBAUD */
  1494.  
  1495.  
  1496. /* load rs232 baud rate, returns -1 if not known */
  1497. int getbaud ()
  1498. {
  1499.     register int    i;
  1500.     int    tv;            /* Timer value */
  1501.     int    maxtv;            /* Maximum timer value */
  1502.     unsigned long    endhz;        /* End of polling period */
  1503.     long    savessp;        /* Old stack pointer */
  1504.  
  1505.     savessp = Super(0L);
  1506.     maxtv = 0;
  1507.     endhz = *hz_200 + 8;
  1508.     while (*hz_200 < endhz)
  1509.     {
  1510.         tv = *((unsigned char *) (MFP + TDDR));
  1511.         if (tv > maxtv)
  1512.             maxtv = tv;
  1513.     }
  1514.     (void) Super(savessp);
  1515.     for (i = sizeof(timevals) / sizeof(timevals[0]);
  1516.       --i >= 0 && timevals[i] != maxtv; );
  1517. #ifdef    HIBAUD
  1518.     if (i >= 0) {
  1519.         for (tv = 0;
  1520.          vbauds[tv].sbaud != NULL || vbauds[tv].ibaud != i; tv++);
  1521.         if (vbauds[tv].sbaud != NULL)
  1522.             return(tv);
  1523.     }
  1524. #endif /* HIBAUD */
  1525.     return(i);
  1526. }
  1527.  
  1528. /* -eof- */
  1529.